package demo2;

public class Test {


    public static void main1(String[] args) {
//            InnerClass innerClass = new InnerClass();
        OuterClass1.InnerClass innerClass = new OuterClass1.InnerClass();
        innerClass.func();
    }

    public static void main2(String[] args) {
        OuterClass.InnerClass innerClass = new OuterClass().new InnerClass();
        OuterClass outerClass = new OuterClass();
        OuterClass.InnerClass innerClass1 = outerClass.new InnerClass();
        innerClass.func();
        outerClass.test();


    }

    public static void main3(String[] args) {
        OuterClass2 outerClass2 = new OuterClass2();
        outerClass2.func();
    }

    public static void main(String[] args) {

        IA ia = new AA();//1
        ia.func();

        //实例化接口--》错误 匿名内部类
        //
        new IA(){

            @Override
            public void func() {
                System.out.println("hahahahahahahha");
            }
        }.func();//2
        //1和2是等价的，都是类实现了接口，然后实例化类，但是只是2实例化的类没有名字，所以叫做匿名内部类
    }


}

//匿名内部类
interface IA {

    void func();


}

class AA implements IA {

    @Override
    public void func() {
        System.out.println("从此封心锁爱，不爱任何人");
    }
}




//局部内部类：定义在外部类的方法体或者{}当中，该种内部类只能在其定义的位置使用，一般使用比较少
//局部内部类只能定义在所定义的方法内部使用，也有对应的字节码文件


class OuterClass2 {

    public void func() {
        //只能在func当中使用
        class InnerClass {
            public int a = 1;
            public void test() {
                System.out.println("hello");
            }
        }

        InnerClass innerClass = new InnerClass();
        innerClass.test();
    }
}

//非静态内部类对象的实例化，必须依靠依靠外部类对象的引用。才能实例化
//实例内部类比较麻烦，需要外部类的对象而静态内部类不需要
//外部类可以访问非静态内部类的所有成员，即使是private也可以访问
//非静态内部类和外部类有同名成员--》就近原则
//如果想要访问外部类的同名变量呢？？？
// this.data   访问自己的
// 外部类名.this.data  访问外部类的
//在非静态内部类当中，包含外部类的this的

class OuterClass {
    public int data1 = 1;
    public int data2 = 2;
    public static int data3 = 3;

    //在实例内部类当中，不能定义静态的成员变量,如果一定要定义，可以加final
    //常量在编译时候，就确定了
    class InnerClass {
        //非静态内部类
        public int data1 = 1111;
        public int data4 = 4;
        private int data5 = 5;
//        public static int data6 = 6;
        public static final int data6 = 67;

        //此时这个非静态内部类，当外部类被加载是，这个静态内部类不会被加载，所以在非静态内部类
        //内部不能定义静态成员变量

        public void func() {
            System.out.println("InnerCalss-->func");
            System.out.println("++++++" + this.data1);
            System.out.println(OuterClass.this.data1);
            System.out.println(data1);
            System.out.println(data2);
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println(data6);
        }
    }

    public void test() {
        InnerClass innerClass = new InnerClass();
        System.out.println("InnerCalss-->func");
        System.out.println(data1);
        System.out.println(data2);
        System.out.println(data3);
        System.out.println(innerClass.data4);
        System.out.println(innerClass.data5);
        System.out.println(InnerClass.data6);

    }
}

//如何实例化静态内部类的对象--->通过外部类类名的引用实例化静态内部类对象
//在静态内部类当中，不能直接访问外部类的非静态成员
//静态内部类生成的字节码文件名： 外部类名$内部类.class


//外部类
class OuterClass1 {
    public int data1 = 1;
    public int data2 = 2;
    public static int data3 = 3;

    static class InnerClass {
        //静态内部类

        public int data4 = 4;
        private int data5 = 5;
        public static int data6 = 6;

        public void func() {
            System.out.println("static InnerCalss-->func");
//            System.out.println(data1);
//            System.out.println(data2);
            //必须通过外部类对象的引用才能访问，所以在静态内部类这里不能直接访问到

            OuterClass1 outerClass = new OuterClass1();
            System.out.println(outerClass.data1);
            System.out.println(outerClass.data2);
            System.out.println(data3);
            System.out.println(this.data4);
            //代表内部类对象的引用
            System.out.println(data5);
            System.out.println(data6);
        }
    }

    public void test() {
        InnerClass innerClass = new InnerClass();
        System.out.println(data1);
        System.out.println(data2);
        System.out.println(data3);
        System.out.println(innerClass.data4);
        //data5是private修饰的，外部类可以访问静态内部类当中的所有成员，即使是private修饰的
        System.out.println(innerClass.data5);
        //静态成员变量---》通过类名访问
        System.out.println(InnerClass.data6);
    }
}



